﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace CuteAnt
{
  internal sealed class ValidationHelper
  {
    /// <summary>Value for lining method</summary>
    private const MethodImplOptions AggressiveInlining = (MethodImplOptions)256;

    #region -- method ArgumentNullOrEmpty --

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentNullOrEmpty(String value, String parameterName)
    {
      ArgumentNullOrEmpty(value, parameterName, "'{0}' cannot be empty.");
    }

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentNullOrEmpty(String value, String parameterName, String message)
    {
      if (value == null)
      {
        throw new ArgumentNullException(parameterName);
      }
      else
      {
        for (Int32 i = 0; i < value.Length; i++)
        {
          if (!Char.IsWhiteSpace(value[i])) { return; }
        }
        throw new ArgumentException(string.Format(message, parameterName), parameterName);
      }
    }

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentNullOrEmpty<T>(ICollection<T> collection, String parameterName)
    {
      ArgumentNullOrEmpty<T>(collection, parameterName, string.Format("Collection '{0}' cannot be empty.", parameterName));
    }

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentNullOrEmpty<T>(ICollection<T> collection, String parameterName, String message)
    {
      if (collection == null)
      {
        throw new ArgumentNullException(parameterName);
      }
      if (collection.Count == 0)
      {
        throw new ArgumentException(message, parameterName);
      }
    }

    #endregion

    #region -- method ArgumentNull --

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentNull<T>(T value, String parameterName) where T : class
    {
      if (value == null)
      {
        throw new ArgumentNullException(parameterName);
      }
    }

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentNull<T>(T value, String parameterName, String message)
    {
      if (value == null)
      {
        throw new ArgumentNullException(parameterName, string.Format(message, parameterName));
      }
    }

    #endregion

    #region -- method ArgumentCondition --

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentCondition(Boolean condition, String message)
    {
      if (condition)
      {
        throw new ArgumentException(message);
      }
    }

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentCondition(Boolean condition, String parameterName, String message)
    {
      if (condition)
      {
        throw new ArgumentException(string.Format(message, parameterName), parameterName);
      }
    }

    #endregion

    #region -- method ArgumentOutOfRangeCondition --

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentOutOfRangeCondition(Boolean condition, String parameterName)
    {
      if (condition)
      {
        throw new ArgumentOutOfRangeException(parameterName);
      }
    }

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentOutOfRangeCondition(Boolean condition, String parameterName, String message)
    {
      if (condition)
      {
        throw new ArgumentOutOfRangeException(parameterName, string.Format(message, parameterName));
      }
    }

    #endregion

    #region -- method ArgumentTypeIsEnum --

    [MethodImpl(AggressiveInlining)]
    public static void ArgumentTypeIsEnum(Type enumType, String parameterName)
    {
      ArgumentNull(enumType, "enumType");
      if (!enumType.IsEnum)
      {
        throw new ArgumentException(string.Format("Type {0} is not an Enum.", enumType), parameterName);
      }
    }

    #endregion

    #region -- method InvalidOperationCondition --

    [MethodImpl(AggressiveInlining)]
    public static void InvalidOperationCondition(Boolean condition, String message)
    {
      if (condition)
      {
        throw new InvalidOperationException(message);
      }
    }

    #endregion

    #region -- method ObjectDisposedCondition --

    [MethodImpl(AggressiveInlining)]
    public static void ObjectDisposedCondition(Boolean condition, String objectName)
    {
      if (condition)
      {
        throw new ObjectDisposedException(objectName);
      }
    }

    [MethodImpl(AggressiveInlining)]
    public static void ObjectDisposedCondition(Boolean condition, String objectName, String message)
    {
      if (condition)
      {
        throw new ObjectDisposedException(objectName, string.Format(message, objectName));
      }
    }

    #endregion

    //public static void NotNull<T>(T value) where T : class
    //{
    //	Debug.Assert(value != null);
    //}

    //[Conditional("DEBUG")]
    //public static void NotNull<T>(T? value) where T : struct
    //{
    //	Debug.Assert(value != null);
    //}
    //public static void NotEmpty(string value)
    //{
    //	Debug.Assert(!string.IsNullOrWhiteSpace(value));
    //}
  }
}